import 'dart:io';
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:csp_amap_flutter_location/amap_flutter_location.dart';
import 'package:csp_amap_flutter_location/amap_location_option.dart';
import 'package:permission_handler/permission_handler.dart';

/// 应用入口函数
void main() {
  runApp(new MyApp());
}

/// 应用主类
/// 展示高德地图定位功能的示例应用
class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => new _MyAppState();
}

/// 应用状态类
/// 管理定位功能和UI展示
class _MyAppState extends State<MyApp> {
  /// 存储定位结果
  Map<String, Object>? _locationResult;

  /// 定位结果监听器
  StreamSubscription<Map<String, Object>>? _locationListener;

  /// 高德定位插件实例
  final AMapFlutterLocation _locationPlugin = new AMapFlutterLocation();

  @override
  void initState() {
    super.initState();

    /// 设置是否已经包含高德隐私政策并弹窗展示显示用户查看，如果未包含或者没有弹窗展示，高德定位SDK将不会工作
    ///
    /// 高德SDK合规使用方案请参考官网地址：https://lbs.amap.com/news/sdkhgsy
    /// <b>必须保证在调用定位功能之前调用， 建议首次启动App时弹出《隐私政策》并取得用户同意</b>
    ///
    /// 高德SDK合规使用方案请参考官网地址：https://lbs.amap.com/news/sdkhgsy
    ///
    /// [hasContains] 隐私声明中是否包含高德隐私政策说明
    ///
    /// [hasShow] 隐私权政策是否弹窗展示告知用户
    AMapFlutterLocation.updatePrivacyShow(true, true);

    /// 设置是否已经取得用户同意，如果未取得用户同意，高德定位SDK将不会工作
    ///
    /// 高德SDK合规使用方案请参考官网地址：https://lbs.amap.com/news/sdkhgsy
    ///
    /// <b>必须保证在调用定位功能之前调用, 建议首次启动App时弹出《隐私政策》并取得用户同意</b>
    ///
    /// [hasAgree] 隐私权政策是否已经取得用户同意
    AMapFlutterLocation.updatePrivacyAgree(true);

    /// 动态申请定位权限
    requestPermission();

    /// 设置Android和iOS的apiKey
    /// key的申请请参考高德开放平台官网说明
    /// Android: https://lbs.amap.com/api/android-location-sdk/guide/create-project/get-key
    /// iOS: https://lbs.amap.com/api/ios-location-sdk/guide/create-project/get-key
    AMapFlutterLocation.setApiKey(
        "1dbf56e2e8a4d0e4cdc2df9efd36bc71", "dfb64c0463cb53927914364b5c09aba0",
        ohosKey: "1dbf56e2e8a4d0e4cdc2df9efd36bc71");

    /// iOS 获取native精度类型
    /// 仅在iOS平台上检查定位精度授权状态
    if (Platform.isIOS) {
      requestAccuracyAuthorization();
    }

    /// 注册定位结果监听
    /// 通过监听器接收定位结果并更新UI
    _locationListener = _locationPlugin
        .onLocationChanged()
        .listen((Map<String, Object> result) {
      setState(() {
        _locationResult = result;
      });
    });
  }

  @override
  void dispose() {
    super.dispose();

    /// 移除定位监听
    /// 防止内存泄漏
    if (null != _locationListener) {
      _locationListener?.cancel();
    }

    /// 销毁定位
    /// 释放定位资源
    _locationPlugin.destroy();
  }

  /// 设置定位参数
  /// 配置定位选项，如精度、频率等
  void _setLocationOption() {
    AMapLocationOption locationOption = new AMapLocationOption();

    /// 是否单次定位
    /// false表示连续定位
    locationOption.onceLocation = true;

    /// 是否需要返回逆地理信息
    /// true表示需要返回地址信息
    locationOption.needAddress = true;

    /// 是否需要返回逆地理编码信息
    locationOption.locatingWithReGeocode = true;

    /// 逆地理信息的语言类型
    /// 默认为自动适配当前系统语言
    locationOption.geoLanguage = GeoLanguage.DEFAULT;

    /// iOS 14定位精度权限设置
    /// 设置为模糊定位精度
    locationOption.desiredLocationAccuracyAuthorizationMode =
        AMapLocationAccuracyAuthorizationMode.ReduceAccuracy;

    /// iOS 14精确定位目的key
    /// 需要与info.plist中配置一致
    locationOption.fullAccuracyPurposeKey = "AMapLocationScene";

    /// 设置Android端连续定位的定位间隔
    /// 单位：毫秒
    locationOption.locationInterval = 2000;

    /// 设置Android端的定位模式
    /// 可选值：
    /// [AMapLocationMode.Battery_Saving] 低功耗模式
    /// [AMapLocationMode.Device_Sensors] 仅设备模式
    /// [AMapLocationMode.Hight_Accuracy] 高精度模式
    locationOption.locationMode = AMapLocationMode.Hight_Accuracy;

    /// 设置iOS端的定位最小更新距离
    /// -1表示不限制距离
    locationOption.distanceFilter = -1;

    /// 设置iOS端期望的定位精度
    /// 可选值：
    /// [DesiredAccuracy.Best] 最高精度
    /// [DesiredAccuracy.BestForNavigation] 适用于导航场景的高精度
    /// [DesiredAccuracy.NearestTenMeters] 10米
    /// [DesiredAccuracy.Kilometer] 1000米
    /// [DesiredAccuracy.ThreeKilometers] 3000米
    locationOption.desiredAccuracy = DesiredAccuracy.Best;

    /// 设置iOS端是否允许系统暂停定位
    /// false表示不允许系统暂停定位
    locationOption.pausesLocationUpdatesAutomatically = false;

    /// 将定位参数设置给定位插件
    _locationPlugin.setLocationOption(locationOption);
  }

  /// 开始定位
  /// 设置定位参数并启动定位
  void _startLocation() {
    /// 开始定位之前设置定位参数
    _setLocationOption();
    _locationPlugin.startLocation();
  }

  /// 停止定位
  /// 停止定位服务
  void _stopLocation() {
    _locationPlugin.stopLocation();
  }

  /// 创建按钮容器
  /// 包含开始定位和停止定位两个按钮
  Container _createButtonContainer() {
    return new Container(
        alignment: Alignment.center,
        child: new Row(
          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            new ElevatedButton(
              onPressed: _startLocation,
              child: const Text('开始定位'),
              style: ButtonStyle(
                backgroundColor: WidgetStateProperty.all(Colors.blue),
                foregroundColor: WidgetStateProperty.all(Colors.white),
              ),
            ),
            new Container(width: 20.0),
            new ElevatedButton(
              onPressed: _stopLocation,
              child: const Text('停止定位'),
              style: ButtonStyle(
                backgroundColor: WidgetStateProperty.all(Colors.blue),
                foregroundColor: WidgetStateProperty.all(Colors.white),
              ),
            )
          ],
        ));
  }

  /// 创建结果显示组件
  /// 用于显示定位结果的每一项键值对
  /// @param key 定位结果的键
  /// @param value 定位结果的值
  Widget _resultWidget(key, value) {
    return new Container(
      child: new Row(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: <Widget>[
          new Container(
            alignment: Alignment.centerRight,
            width: 100.0,
            child: new Text('$key :'),
          ),
          new Container(width: 5.0),
          new Flexible(child: new Text('$value', softWrap: true)),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    List<Widget> widgets = <Widget>[];
    widgets.add(_createButtonContainer());

    if (_locationResult != null) {
      _locationResult?.forEach((key, value) {
        widgets.add(_resultWidget(key, value));
      });
    }

    return new MaterialApp(
        home: new Scaffold(
      appBar: new AppBar(
        title: const Text('ST AMap Location plugin example app'),
      ),
      body: new Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        mainAxisSize: MainAxisSize.min,
        children: widgets,
      ),
    ));
  }

  ///获取iOS native的accuracyAuthorization类型
  void requestAccuracyAuthorization() async {
    AMapAccuracyAuthorization currentAccuracyAuthorization =
        await _locationPlugin.getSystemAccuracyAuthorization();
    if (currentAccuracyAuthorization ==
        AMapAccuracyAuthorization.AMapAccuracyAuthorizationFullAccuracy) {
      print("精确定位类型");
    } else if (currentAccuracyAuthorization ==
        AMapAccuracyAuthorization.AMapAccuracyAuthorizationReducedAccuracy) {
      print("模糊定位类型");
    } else {
      print("未知定位类型");
    }
  }

  /// 动态申请定位权限
  void requestPermission() async {
    // 申请权限
    bool hasLocationPermission = await requestLocationPermission();
    if (hasLocationPermission) {
      print("定位权限申请通过");
    } else {
      print("定位权限申请不通过");
    }
  }

  /// 申请定位权限
  /// 授予定位权限返回true， 否则返回false
  Future<bool> requestLocationPermission() async {
    //获取当前的权限
    var status = await Permission.location.status;
    if (status == PermissionStatus.granted) {
      //已经授权
      return true;
    } else {
      //未授权则发起一次申请
      status = await Permission.location.request();
      if (status == PermissionStatus.granted) {
        return true;
      } else {
        return false;
      }
    }
  }
}
